﻿using System;
using System.Windows.Forms;
using System.ComponentModel.Design;
using System.Drawing.Design;
using VisualPureBasicIDE.FormDesigner.Implementations;

namespace VisualPureBasicIDE.FormDesigner
{
    public partial class Designer : WeifenLuo.WinFormsUI.Docking.DockContent
    {
        DesignerHost _host;
        ServiceContainer _serviceContainer;
        private readonly PropertyGrid _propertyGrid;
        private readonly ToolboxService _toolboxServiceImpl;

        public Designer(PropertyGrid propertyGridToUse, ToolboxService toolboxServiceImplToUse)
        {
            _propertyGrid = propertyGridToUse;
            _toolboxServiceImpl = toolboxServiceImplToUse;
            InitializeComponent();
            InitWindow();
        }

        #region private methods

        private void InitWindow()
        {
            _serviceContainer = new ServiceContainer();
            // Create host
            _host = new DesignerHost(_serviceContainer, this);

            AddBaseServices();

            var form = (Form)_host.CreateComponent(typeof(Form), null);
            form.TopLevel = false;
            form.Text = "New window";
            var rootDesigner = (IRootDesigner)_host.GetDesigner(form);
            var designView = (Control)rootDesigner.GetView(ViewTechnology.Default);
            designView.Dock = DockStyle.Fill;
            designSurfacePanel.Controls.Add(designView);
            // We need to subscribe to selection changed events so 
            // that we can update our properties grid
            var selectionService = _host.GetService(typeof(ISelectionService)) as ISelectionService;
            if (selectionService != null)
                selectionService.SelectionChanged += SelectionServiceSelectionChanged;
            // Activate the host
            _host.Activate();
        }

        private static FdToolbox LoadPureBasicGadgets()
        {
            var tools = new FdToolbox();
            var myCategories = new[] { new Category() };
            myCategories[0].DisplayName = "Gadgets";
            var myItems = new FdToolboxItem[1];
            for (var i = 0; i < 1; i++) { myItems[i] = new FdToolboxItem(); }
            myItems[0].Type = "VisualPureBasicIDE.PureBasic.Forms.Gadgets.ButtonGadget,VisualPureBasicIDE.PureBasicBinding";
            // TODO: Implement all the other gadgets
            myCategories[0].FdToolboxItem = myItems;
            tools.FdToolboxCategories = myCategories;
            return tools;
        }

        private void AddBaseServices()
        {
            _toolboxServiceImpl.LoadToolbox(LoadPureBasicGadgets());
            // Add service
            _serviceContainer.AddService(typeof(IToolboxService), _toolboxServiceImpl);
        }

        #endregion

        protected override object GetService(Type service)
        {
            if (_serviceContainer != null && _serviceContainer.GetService(service) != null)
            {
                return _serviceContainer.GetService(service);
            }
            return _host != null ? _host.GetService(service) : null;
        }

        private void menuEditDelete_Click(object sender, EventArgs e)
        {
            var menuCommandService = GetService(typeof(IMenuCommandService)) as IMenuCommandService;
            if (menuCommandService != null) menuCommandService.GlobalInvoke(StandardCommands.Delete);
        }

        private void SelectionServiceSelectionChanged(object sender, EventArgs e)
        {
            var selectionService = _host.GetService(typeof(ISelectionService)) as ISelectionService;
            
            if (_propertyGrid == null || selectionService == null) return;

            var selectedComponents = selectionService.GetSelectedComponents();

            // If nothing is selected, just select the root component
            if (selectedComponents.Count == 0)
            {
                _propertyGrid.SelectedObjects = new object[] { _host.RootComponent };
            }

            // We have to copy over the selected components list
            // into an array and then set the selectedObjects property
            var selections = new Object[selectedComponents.Count];
            selectedComponents.CopyTo(selections, 0);
            if (selections.Length != 0) _propertyGrid.SelectedObject = selections[selections.Length - 1];
        }

        private void formMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Clear gadget list and object inspector
            _toolboxServiceImpl.ToolboxView.Nodes.Clear();
            _toolboxServiceImpl.ToolboxView.ImageList = null;
            _toolboxServiceImpl.ToolboxView.Nodes.Add("(No designer opened)");
            _propertyGrid.SelectedObjects = null;
        }
    }
}